using System;
using System.Data;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Threading;
using System.Drawing.Text;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using needle.UI.Controls.Flat.Utilities.Drawing;

namespace needle.UI.Controls.Flat.Windows.Forms
{
	[DefaultEvent("ButtonPressed"),
	System.ComponentModel.ToolboxItem(true)]
	public class Button : needle.UI.Controls.Flat.Windows.Forms.ControlBase, needle.UI.Controls.Flat.Windows.Forms.IFlashabledControl
	{		
		private System.ComponentModel.Container components  = null;
		private string m_Text = String.Empty;
		private Single m_Radius = 0;

		//Style Neo, default!!
		private Color m_TextColor = Color.Black;
		private Color m_FlashColor = Color.FromArgb(170, 170, 221);
		private Color m_ButtonColor = Color.FromArgb(242, 242, 228);
		private Color m_ButtonHotColor = Color.FromArgb(231, 231, 214);
		private Color m_ButtonPressedColor = Color.FromArgb(222, 217, 207);

		[Category("Action")]
		public event ButtonPressedEventHandler ButtonPressed = null;

		#region Constructors
		
		public Button()
		{
			InitializeComponent();
		}

		#endregion

		#region Dispose

		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#endregion

		#region Component Designer generated code

		private void InitializeComponent()
		{
			// 
			// EnterpriseButton
			// 
			this.Name = "Button";
			this.Size = new System.Drawing.Size(70, 25);
		}
		
		#endregion

		#region Overrides

		protected override void OnStyleChanged(object sender, StyleEventArgs args)
		{
			base.OnStyleChanged(sender, args);

			if (args.PropertyName == "ButtonTextColor") {this.TextColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "ButtonFlashColor") {this.m_FlashColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "ButtonColor") {this.m_ButtonColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "ButtonHotColor") {this.m_ButtonHotColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "ButtonPressedColor") {this.m_ButtonPressedColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "ButtonBorderColor") {this.BorderColor = (Color)args.PropertyValue;}
			else if (args.PropertyName == "ButtonBorderHotColor") {this.BorderHotColor = (Color)args.PropertyValue;}

			this.Invalidate(true);
		}

		protected override void OnPlansOfColorsChanged(object sender, PlansOfColorsChangedEventArgs args)
		{
			base.OnPlansOfColorsChanged(sender, args);

			if (this.Style!=null)
			{
				this.TextColor = this.Style.ButtonTextColor;
				this.m_FlashColor = this.Style.ButtonFlashColor;
				this.m_ButtonColor = this.Style.ButtonColor;
				this.m_ButtonHotColor = this.Style.ButtonHotColor;
				this.m_ButtonPressedColor = this.Style.ButtonPressedColor;
				this.BorderColor = this.Style.ButtonBorderColor;
				this.BorderHotColor = this.Style.ButtonBorderHotColor;
			}

			this.Invalidate(true);
		}

		protected override void DrawControl(Graphics g,bool hot)
		{	
			DrawControl(g,hot,false);
		}
		
		protected override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
		{
			base.OnMouseDown(e);

			if(this.Enabled)
			{
				using(Graphics g = this.CreateGraphics())
				{
					DrawControl(g,true,true);
				}
			}
		}

		protected override void OnMouseUp(System.Windows.Forms.MouseEventArgs e)
		{
			base.OnMouseUp(e);

			if(this.Enabled && this.IsMouseInControl)
			{
				using(Graphics g = this.CreateGraphics())
				{
					DrawControl(g,this.Focused,false);
				}

				OnButtonClicked();
			}
		}

		protected override void OnKeyDown(System.Windows.Forms.KeyEventArgs e)
		{
			base.OnKeyDown(e);

			if(this.Enabled && (e.KeyData == Keys.Space))
			{
				using(Graphics g = this.CreateGraphics())
				{
					DrawControl(g,true,true);
				}

				OnButtonClicked();
			}
		}

		protected override void OnKeyUp(System.Windows.Forms.KeyEventArgs e)
		{
			base.OnKeyUp(e);

			if(this.Enabled && (e.KeyData == Keys.Space || e.KeyData == Keys.Enter))
			{
				using(Graphics g = this.CreateGraphics())
				{
					DrawControl(g,this.Focused,false);
				}				
			}
		}

		protected override bool ProcessMnemonic(char charCode)
		{
			if (this.CanSelect && IsMnemonic(charCode, m_Text))
			{
				OnButtonClicked();
				this.Focus();
				return true;
			}
			else {return false;}
		}

		#endregion

		#region Virtuals

		protected virtual void OnButtonClicked()
		{
			if(this.ButtonPressed != null)
			{
				this.ButtonPressed(this,new System.EventArgs());
			}
		}

		protected virtual void DrawControl(Graphics g,bool hot,bool pressed)
		{
			if (this.Radius > 0)
			{
				g.SmoothingMode = SmoothingMode.AntiAlias;

				this.BackColor = this.Parent.BackColor;

				using (Brush brush1 = new SolidBrush(this.ForeColor),
						   brush2 = new SolidBrush(Color.Silver))
				{
					Rectangle groupRect = new Rectangle(-1,-1, this.Width+1, this.Height+1);

					if (base.Style != null)
					{
						using (Pen pen1=new Pen(base.Style.InteliButtonBorderColor(hot),2))
						{
							GraphicsPath path = DrawHelpers.GetRoundedRect(groupRect, this.m_Radius);
							g.DrawPath(pen1, path);
			
							using (Brush brush3 = new SolidBrush(base.Style.InteliButtonColor(hot,pressed)))
							{
								g.FillPath(brush3, path);
							}
						}
					}
					else
					{
						using (Pen pen2=new Pen(StyleGuide.InteliBorderColor(hot, base.BorderHotColor, base.BorderColor),2))
						{
							GraphicsPath path = DrawHelpers.GetRoundedRect(groupRect, this.m_Radius);
							g.DrawPath(pen2, path);
			
							using (Brush brush3 = new SolidBrush(StyleGuide.InteliButtonColor(hot,pressed, this.m_ButtonColor,
									   this.m_ButtonPressedColor, this.m_ButtonHotColor)))
							{
								g.FillPath(brush3, path);
							}
						}
					}
		
					StringFormat format  = new StringFormat();
					format.LineAlignment = StringAlignment.Center;
					format.Alignment     = StringAlignment.Center;
					format.HotkeyPrefix  = HotkeyPrefix.Show;

					Rectangle txtRect = this.ClientRectangle;

					if(pressed)
					{
						txtRect.Location = new Point(txtRect.Left+1,txtRect.Top+1);
					}

					if(this.Enabled)
					{
						g.DrawString(m_Text,this.Font,brush1,txtRect,format);
					}
					else
					{
						g.DrawString(m_Text,this.Font,brush2,txtRect,format);
					}
				}
			}
			else
			{
				using (Brush brush1 = new SolidBrush(this.ForeColor),
						   brush2 = new SolidBrush(Color.FromArgb(128,128,128)))
				{
					if (base.Style != null)
					{
						using (Pen pen1=new Pen(base.Style.InteliButtonBorderColor(hot),2))
						{
							g.Clear(base.Style.InteliButtonColor(hot,pressed));
							g.DrawRectangle(pen1,this.ClientRectangle);
						}
					}
					else
					{
						using (Pen pen2=new Pen(StyleGuide.InteliBorderColor(hot, base.BorderHotColor, base.BorderColor),2))
						{
							g.Clear(StyleGuide.InteliButtonColor(hot,pressed, this.m_ButtonColor, this.m_ButtonPressedColor, this.m_ButtonHotColor));
							g.DrawRectangle(pen2,this.ClientRectangle);
						}
					}
		
					StringFormat format  = new StringFormat();
					format.LineAlignment = StringAlignment.Center;
					format.Alignment     = StringAlignment.Center;
					format.HotkeyPrefix  = HotkeyPrefix.Show;

					Rectangle txtRect = this.ClientRectangle;

					if(pressed)
					{
						txtRect.Location = new Point(txtRect.Left+1,txtRect.Top+1);
					}

					if(this.Enabled)
					{
						g.DrawString(m_Text,this.Font,brush1,txtRect,format);
					}
					else
					{
						g.DrawString(m_Text,this.Font,brush2,txtRect,format);
					}
				}
			}
		}

		#endregion

		#region Internal helpers

		private void ThreadFlashControl()
		{
			for (int i=1; i<=8;i++)
			{
				if(this.ForeColor == this.TextColor)
				{
					this.ForeColor = this.FlashColor;
				}
				else
				{
					this.ForeColor = this.TextColor;
				}
				Thread.Sleep(150);
			}

			this.ForeColor = this.TextColor;
		}

		#endregion

		#region Properties

		[Category("Appearance")]
		public Single Radius
		{
			get
			{ 
				return m_Radius; 
			}
			set
			{
				m_Radius = value;
				this.Invalidate(false);
			}
		}

		[Browsable(true),
		DesignerSerializationVisibility(DesignerSerializationVisibility.Visible),
		Bindable(true)]
		public override string Text
		{
			get {return m_Text;}
			set
			{ 
				m_Text = value; 
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color TextColor
		{
			get {return m_TextColor;}
			set 
			{
				m_TextColor = value;
				this.ForeColor = value;
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color FlashColor
		{
			get {return m_FlashColor;}
			set 
			{
				m_FlashColor = value;
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color ButtonColor
		{
			get {return m_ButtonColor;}
			set 
			{
				m_ButtonColor = value;
				this.BackColor = m_ButtonColor;
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color ButtonHotColor
		{
			get {return m_ButtonHotColor;}
			set 
			{
				m_ButtonHotColor = value;
				this.Invalidate();
			}
		}

		[Category("Style")]
		public Color ButtonPressedColor
		{
			get {return m_ButtonPressedColor;}
			set 
			{
				m_ButtonPressedColor = value;
				this.Invalidate();
			}
		}

		#endregion

		#region IFlashabledControl

		public void FlashControl()
		{
			Thread m_Thread = new Thread(new ThreadStart(ThreadFlashControl));
			m_Thread.Start();
		}
		
		#endregion
	}
}